/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.udt.designtime.api.entity;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.inspur.edp.cef.designtime.api.element.EnumIndexType;
import com.inspur.edp.cef.designtime.api.element.GspElementDataType;
import com.inspur.edp.cef.designtime.api.element.GspElementObjectType;
import com.inspur.edp.cef.designtime.api.collection.GspAssociationCollection;
import com.inspur.edp.cef.designtime.api.collection.GspEnumValueCollection;
import com.inspur.edp.cef.designtime.api.IFieldCollection;
import com.inspur.edp.lcm.metadata.api.IMetadataContent;
import com.inspur.edp.udt.designtime.api.entity.dbInfo.ColumnInfo;
import com.inspur.edp.udt.designtime.api.entity.element.ElementCollection;
import com.inspur.edp.udt.designtime.api.entity.element.UdtElement;
import com.inspur.edp.udt.designtime.api.entity.enumtype.UseType;
import com.inspur.edp.udt.designtime.api.json.SimpleDataTypeDeserializer;
import com.inspur.edp.udt.designtime.api.json.SimpleDataTypeSerializer;
import com.inspur.edp.udt.designtime.api.utils.UdtUtils;


/**
 * 简单类型UDT
 */
@JsonDeserialize(using = SimpleDataTypeDeserializer.class)
@JsonSerialize(using = SimpleDataTypeSerializer.class)
public class SimpleDataTypeDef extends UnifiedDataTypeDef implements IMetadataContent {
	/**
	 * 基础数据类型
	 * <see cref="GSPElementDataType"/>
	 */
	public GspElementDataType getMDataType() {
		return (GspElementDataType) getPropertys().getPropertyName("DataType").getPropertyValue();

	}

	public void setMDataType(GspElementDataType value) {
		getPropertys().getPropertyName("DataType").setPropertyValue(value);
	}

	/**
	 * 字段的物理长度
	 * <see cref="int"/>
	 */
	public int getLength() {
		return (int) getPropertys().getPropertyName("Length").getPropertyValue();

	}

	public void setLength(int value) {
		getPropertys().getPropertyName("Length").setPropertyValue(value);

	}

	/**
	 * 字段精度
	 * <see cref="int"/>
	 */
	public int getPrecision() {
		return (int) getPropertys().getPropertyName("Precision").getPropertyValue();
	}

	public void setPrecision(int value) {
		getPropertys().getPropertyName("Precision").setPropertyValue(value);
	}

	/**
	 * 默认值
	 * <see cref="object"/>
	 */
	public Object getDefaultValue() {
		return getPropertys().getPropertyName("DefaultValue").getPropertyValue();
	}

	public void setDefaultValue(Object value) {

		getPropertys().getPropertyName("DefaultValue").setPropertyValue(value);
	}

	/**
	 * 是否唯一
	 * <see cref="bool"/>
	 */
	public boolean getIsUnique() {

		return (boolean) getPropertys().getPropertyName("IsUnique").getPropertyValue();
	}

	public void setIsUnique(boolean value) {
		getPropertys().getPropertyName("IsUnique").setPropertyValue(value);
	}


	/**
	 * 是否必填
	 * <see cref="bool"/>
	 */
	public boolean getIsRequired() {
		return (boolean) getPropertys().getPropertyName("IsRequired").getPropertyValue();

	}

	public void setIsRequired(boolean value) {
		getPropertys().getPropertyName("IsRequired").setPropertyValue(value);
	}
	/**
	 *
	 * 是否去掉数据结尾空格
	 */

	public boolean isEnableRtrim() {
		return (boolean)getPropertys().getPropertyName("EnableRtrim").getPropertyValue();
	}

	public void setEnableRtrim(boolean value) {
		getPropertys().getPropertyName("EnableRtrim").setPropertyValue(value);
	}

	/**
	 * 对象类型
	 * <see cref="GSPElementObjectType"/>
	 */
	public GspElementObjectType getObjectType() {
		return (GspElementObjectType) getPropertys().getPropertyName("ObjectType").getPropertyValue();

	}

	public void setObjectType(GspElementObjectType value) {
		getPropertys().getPropertyName("ObjectType").setPropertyValue(value);

	}

	private GspAssociationCollection childAssociations;

	/**
	 * 关联信息
	 * <see cref="GspAssociationCollection "/>
	 */
	public final GspAssociationCollection getChildAssociations() {
		if ((GspAssociationCollection) getPropertys().getPropertyName("ChildAssociations").getPropertyValue() == null) {
			getPropertys().getPropertyName("ChildAssociations").setPropertyValue(new GspAssociationCollection());
		}
		return (GspAssociationCollection) getPropertys().getPropertyName("ChildAssociations").getPropertyValue();
	}

	public void setChildAssociations(GspAssociationCollection value) {
		getPropertys().getPropertyName("ChildAssociations").setPropertyValue(value);

	}

	private GspEnumValueCollection enumValueCollection;

	/**
	 * 包含的枚举列表
	 * <see cref="GSPEnumValueCollection"/>
	 */
	public final GspEnumValueCollection getContainEnumValues() {
		if ((GspEnumValueCollection) getPropertys().getPropertyName("ContainEnumValues").getPropertyValue() == null) {
			getPropertys().getPropertyName("ContainEnumValues").setPropertyValue(new GspEnumValueCollection());
		}
		return (GspEnumValueCollection) getPropertys().getPropertyName("ContainEnumValues").getPropertyValue();
	}

	public void setContainEnumValues(GspEnumValueCollection value) {
		getPropertys().getPropertyName("ContainEnumValues").setPropertyValue(value);

	}

    public EnumIndexType getEnumIndexType(){
        if(getPropertys().getPropertyName("EnumIndexType")==null) {
            return EnumIndexType.Integer;
        }
        return (EnumIndexType) getPropertys().getPropertyName("EnumIndexType").getPropertyValue();
    }


    public void setEnumIndexType(EnumIndexType indexType){
        getPropertys().getPropertyName("EnumIndexType").setPropertyValue(indexType);
    }
	//
	public SimpleDataTypeDef() {
		//后续提到新建元数据事件中
		init();
		initData();
	}

	private void init() {
		getPropertyUseTypeInfos().put("DataType", getUseType("DataType", UseType.AsConstraint, false));
		getPropertyUseTypeInfos().put("Length", getUseType("Length", UseType.AsConstraint, false));
		getPropertyUseTypeInfos().put("Precision", getUseType("Precision", UseType.AsConstraint, false));
		getPropertyUseTypeInfos().put("DefaultValue", getUseType("DefaultValue", UseType.AsConstraint));
		getPropertyUseTypeInfos().put("ObjectType", getUseType("ObjectType", UseType.AsConstraint, false));
		getPropertyUseTypeInfos().put("ChildAssociations", getUseType("ChildAssociations", UseType.AsConstraint, false));
		getPropertyUseTypeInfos().put("ContainEnumValues", getUseType("ContainEnumValues", UseType.AsConstraint, false));
		getPropertyUseTypeInfos().put("IsUnique", getUseType("IsUnique"));
		getPropertyUseTypeInfos().put("IsRequired", getUseType("IsRequired"));
		getPropertyUseTypeInfos().put("EnableRtrim", getUseType("EnableRtrim"));
		getPropertyUseTypeInfos().put("IsMultiLanguage", getUseType("IsMultiLanguage"));
		getPropertyUseTypeInfos().put("IsRequire", getUseType("IsRequire"));
        getPropertyUseTypeInfos().put("EnumIndexType", getUseType("EnumIndexType"));
	}

	/**
	 * 初始化单值udt
	 */
	public final void initData() {
        getPropertys().add(getPropertyInfo("DataType", GspElementDataType.class, GspElementDataType.String, UseType.AsConstraint, false));
        getPropertys().add(getPropertyInfo("Length", Integer.class, 36, UseType.AsConstraint, false));
        getPropertys().add(getPropertyInfo("Precision", Integer.class, 0, UseType.AsConstraint, false));
        getPropertys().add(getPropertyInfo("DefaultValue", Object.class, null, UseType.AsConstraint));
        getPropertys().add(getPropertyInfo("ObjectType", GspElementObjectType.class, GspElementObjectType.None, UseType.AsConstraint, false)); // 20180802 udt设计时评审，对象类型、关联、枚举为[约束]，且不可更改；
        getPropertys().add(getPropertyInfo("ChildAssociations", GspAssociationCollection.class, null, UseType.AsConstraint, false));
        getPropertys().add(getPropertyInfo("ContainEnumValues", GspEnumValueCollection.class, null, UseType.AsConstraint, false));
        getPropertys().add(getPropertyInfo("IsUnique", Boolean.class, false, UseType.AsTemplate, false));
        getPropertys().add(getPropertyInfo("IsRequired", Boolean.class, false, UseType.AsTemplate, false));
        getPropertys().add(getPropertyInfo("EnableRtrim", Boolean.class, false, UseType.AsTemplate, false));
        getPropertys().add(getPropertyInfo("IsMultiLanguage", Boolean.class, false, UseType.AsTemplate, false));
        getPropertys().add(getPropertyInfo("IsRequire", Boolean.class, false, UseType.AsTemplate, false));
        getPropertys().add(getPropertyInfo("EnumIndexType", EnumIndexType.class, EnumIndexType.Integer, UseType.AsConstraint, false));
    }

	/**
	 * 字段集合
	 * <see cref="IFieldCollection"/>
	 */
	@Override
	public IFieldCollection getContainElements() {
		return createElements();
	}

	private IFieldCollection createElements() {
		ElementCollection tempVar = new ElementCollection();
		UdtElement tempVarSingle = new UdtElement(this.getPropertys());
		tempVarSingle.setID(this.getId());
		tempVarSingle.setCode(this.getCode());
		tempVarSingle.setName(this.getName());
		tempVarSingle.setLabelID(this.getCode());
		tempVarSingle.setIsRequire(this.getIsRequired());
		tempVarSingle.setEnableRtrim(this.isEnableRtrim());
		tempVarSingle.setBelongObject(this);
		tempVarSingle.setI18nResourceInfoPrefix(String.format("%1$s.%2$s", this.getI18nResourceInfoPrefix(), this.getCode()));
		tempVar.add(tempVarSingle);
		return tempVar;
	}

	/**
	 * 更新columns信息
	 */
	@Override
	public void updateColumnsInfo() {
		getColumns().clear();

		ColumnInfo columnInfo = UdtUtils.convertSimpleDataTypeDefToColumnInfo(this);

		getColumns().add(columnInfo);
	}

	/**
	 * 克隆方法
	 *
	 * @return <see cref="object"/>克隆结果
	 */
	public final SimpleDataTypeDef clone() {
		Object tempVar = super.clone();
		Object tempVar2 = getChildAssociations().clone();
		Object tempVar3 = getContainEnumValues().clone();
		SimpleDataTypeDef udt = (SimpleDataTypeDef) ((tempVar instanceof SimpleDataTypeDef) ? tempVar : null);
		if (udt == null) {
			throw new RuntimeException("克隆失败");
		}
		if (getObjectType() == GspElementObjectType.Association && getChildAssociations().size() > 0) {

			udt.setChildAssociations((GspAssociationCollection) ((tempVar2 instanceof GspAssociationCollection) ? tempVar2 : null));
		} else if (getObjectType() == GspElementObjectType.Enum && getContainEnumValues().size() > 0) {

			udt.setContainEnumValues((GspEnumValueCollection) ((tempVar3 instanceof GspEnumValueCollection) ? tempVar3 : null));
		}

		return udt;
	}

}
